package avicit.bdp.dms.tdm.service;

import avicit.bdp.core.constant.Constants;
import avicit.bdp.dms.tdm.dao.AssetCatalogAuthDAO;
import avicit.bdp.dms.tdm.dto.AssetCatalogAuthDTO;
import avicit.platform6.api.system.SysOrgClient;
import avicit.platform6.api.sysuser.dto.SysOrg;
import avicit.platform6.commons.utils.ComUtil;
import avicit.platform6.commons.utils.PojoUtil;
import avicit.platform6.commons.utils.StringUtils;
import avicit.platform6.core.context.ThreadContextHelper;
import avicit.platform6.core.exception.BusinessException;
import avicit.platform6.core.mybatis.pagehelper.PageHelper;
import avicit.platform6.core.properties.PlatformConstant;
import avicit.platform6.core.rest.msg.QueryReqBean;
import avicit.platform6.core.rest.msg.QueryRespBean;
import avicit.platform6.modules.system.syslog.service.SysLogUtil;
import com.github.pagehelper.Page;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;
import org.apache.commons.collections4.CollectionUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

/** 数据共享_供需目录授权Service */
@Service
public class AssetCatalogAuthService {

  private static final Logger logger = LoggerFactory.getLogger(AssetCatalogAuthService.class);

  @Autowired private AssetCatalogAuthDAO assetCatalogAuthDAO;

  @Autowired private SysOrgClient sysOrgClient;

  /** 获取所有一级单位 */
  public List<SysOrg> getAllDept(SysOrg dto) {
    List<SysOrg> resultList = new ArrayList<>();
    List<SysOrg> allSysOrgList = sysOrgClient.getAllSysOrgList();
    if (CollectionUtils.isNotEmpty(allSysOrgList)) {
      // 通过所有部门的Code前缀过滤符合code的数据
      resultList =
          allSysOrgList.stream()
              .filter(sysOrg -> "Y".equalsIgnoreCase(sysOrg.getIsMulOrg()))
              .collect(Collectors.toList());
    }
    // 模糊查询
    /*if (dto != null && StringUtils.isNotEmpty(dto.getOrgName())) {
      resultList =
          resultList.stream()
              .filter(sysOrg -> sysOrg.getOrgName().contains(dto.getOrgName()))
              .collect(Collectors.toList());
    }*/
    return resultList;
  }

  /**
   * 按条件分页查询
   *
   * @param queryReqBean 查询条件
   * @param orgIdentity 组织id
   * @param wordSecret 文档密级
   * @param orderBy 排序
   */
  @Transactional(readOnly = true)
  public QueryRespBean<AssetCatalogAuthDTO> searchByPage(
      QueryReqBean<AssetCatalogAuthDTO> queryReqBean,
      String orgIdentity,
      String wordSecret,
      String orderBy) {
    QueryRespBean<AssetCatalogAuthDTO> queryRespBean = new QueryRespBean<>();
    try {
      PageHelper.startPage(queryReqBean.getPageParameter());
      AssetCatalogAuthDTO searchParams = queryReqBean.getSearchParams();
      Page<AssetCatalogAuthDTO> dataList =
          assetCatalogAuthDAO.searchByPage(
              searchParams, orgIdentity, wordSecret, orderBy, queryReqBean.getKeyWord());
      queryRespBean.setResult(dataList);
      return queryRespBean;
    } catch (Exception e) {
      logger.error(e.getMessage(), e);
      throw new BusinessException("查询失败");
    }
  }

  /** 按条件查询 组织id串 orgIds */
  @Transactional(readOnly = true)
  public List<AssetCatalogAuthDTO> searchListByOrgIds(String orgIds) {
    try {
      return assetCatalogAuthDAO.search(
          orgIds, ThreadContextHelper.getOrgId(), ThreadContextHelper.getWordSecret());
    } catch (Exception e) {
      logger.error(e.getMessage(), e);
      throw new BusinessException("查询失败");
    }
  }

  /**
   * 按条件查询
   *
   * @param queryReqBean 查询条件
   */
  @Transactional(readOnly = true)
  public List<AssetCatalogAuthDTO> searchList(QueryReqBean<AssetCatalogAuthDTO> queryReqBean) {
    try {
      return assetCatalogAuthDAO.searchList(
          queryReqBean.getSearchParams(),
          ThreadContextHelper.getOrgId(),
          ThreadContextHelper.getWordSecret());
    } catch (Exception e) {
      logger.error(e.getMessage(), e);
      throw new BusinessException("查询失败");
    }
  }

  /**
   * 按条件导出
   *
   * @param queryReqBean 查询条件
   * @param orgIdentity 组织id
   * @param wordSecret 文档密级
   * @param orderBy 排序
   */
  @Transactional(readOnly = true)
  public List<AssetCatalogAuthDTO> searchListForExportExcel(
      QueryReqBean<AssetCatalogAuthDTO> queryReqBean,
      String orgIdentity,
      String wordSecret,
      String orderBy) {
    try {
      return assetCatalogAuthDAO.searchListForExportExcel(
          queryReqBean.getSearchParams(),
          orgIdentity,
          wordSecret,
          orderBy,
          queryReqBean.getKeyWord());
    } catch (Exception e) {
      logger.error(e.getMessage(), e);
      throw new BusinessException("导出失败");
    }
  }

  /**
   * 通过主键查询单条记录
   *
   * @param id 主键id
   */
  @Transactional(readOnly = true)
  public AssetCatalogAuthDTO queryByPrimaryKey(String id) {
    try {
      AssetCatalogAuthDTO dto = assetCatalogAuthDAO.findById(id);
      // 记录日志
      if (dto != null) {
        SysLogUtil.log4Query(dto);
      }
      return dto;
    } catch (Exception e) {
      logger.error(e.getMessage(), e);
      throw new BusinessException("通过主键查询单条记录失败");
    }
  }

  /**
   * 目录授权
   *
   * @param orgIds 组织ID串
   * @param catalogIds 供需目录ID串
   */
  @Transactional(rollbackFor = Exception.class)
  public Integer authCatalog(String orgIds, String catalogIds) {
    try {
      if (StringUtils.isEmpty(orgIds)) {
        throw new BusinessException("组织ID为空！");
      }
      List<AssetCatalogAuthDTO> newList = this.processData(orgIds, catalogIds);
      if (CollectionUtils.isNotEmpty(newList)) {
        return this.batchSave(newList);
      }
      return 0;
    } catch (Exception e) {
      logger.error(e.getMessage(), e);
      throw new BusinessException("新增对象失败");
    }
  }

  /**
   * 处理数据
   *
   * @param orgIds 组织ID串
   * @param catalogIds 供需目录ID
   * @return List
   */
  private List<AssetCatalogAuthDTO> processData(String orgIds, String catalogIds) {
    String[] orgIdArray = orgIds.split(Constants.COMMA);
    // 删除旧数据
    this.deleteOldDataBase(orgIdArray);
    if (StringUtils.isEmpty(catalogIds)) {
      return new ArrayList<>();
    }
    String[] catalogIdArray = catalogIds.split(Constants.COMMA);
    List<AssetCatalogAuthDTO> resultList = new ArrayList<>();
    for (String orgId : orgIdArray) {
      for (String catalogId : catalogIdArray) {
        AssetCatalogAuthDTO dto = new AssetCatalogAuthDTO();
        dto.setOrgId(orgId);
        dto.setCatalogId(catalogId);
        dto.setEmpowerStatus("1");
        dto.setStatus("1");
        dto.setSecretLevel("1");
        resultList.add(dto);
      }
    }
    return resultList;
  }

  /**
   * 删除旧数据
   *
   * @param orgIdArray 组织ID数组
   * @return int
   */
  private int deleteOldDataBase(String[] orgIdArray) {
    List<String> orgIdList = new ArrayList<>(Arrays.asList(orgIdArray));
    int result = 0;
    for (String orgId : orgIdList) {
      assetCatalogAuthDAO.deleteByOrgId(orgId);
      result++;
    }
    return result;
  }

  /**
   * 新增对象
   *
   * @param dto 保存对象
   * @return String
   */
  @Transactional
  public String insert(AssetCatalogAuthDTO dto) {
    try {
      dto.setId(ComUtil.getId());
      PojoUtil.setSysProperties(dto, PlatformConstant.OpType.insert);
      assetCatalogAuthDAO.insert(dto);
      // 记录日志
      SysLogUtil.log4Insert(dto);
      return dto.getId();
    } catch (Exception e) {
      logger.error(e.getMessage(), e);
      throw new BusinessException("新增对象失败");
    }
  }

  /**
   * 批量新增对象
   *
   * @param dtoList 保存对象集合
   * @return int
   */
  @Transactional
  public int batchSave(List<AssetCatalogAuthDTO> dtoList) {
    List<AssetCatalogAuthDTO> beanList = new ArrayList<>();
    for (AssetCatalogAuthDTO dto : dtoList) {
      dto.setId(ComUtil.getId());
      PojoUtil.setSysProperties(dto, PlatformConstant.OpType.insert);
      // 记录日志
      SysLogUtil.log4Insert(dto);
      beanList.add(dto);
    }
    try {
      return assetCatalogAuthDAO.batchSave(beanList);
    } catch (Exception e) {
      logger.error(e.getMessage(), e);
      throw new BusinessException("批量新增对象失败");
    }
  }

  /**
   * 修改对象全部字段
   *
   * @param dto 修改对象
   * @return int
   */
  @Transactional
  public int updateAll(AssetCatalogAuthDTO dto) {
    try {
      int ret = assetCatalogAuthDAO.updateAll(getUpdateDto(dto));
      if (ret == 0) {
        throw new BusinessException("数据失效，请重新更新");
      }
      return ret;
    } catch (Exception e) {
      logger.error(e.getMessage(), e);
      throw new BusinessException("修改对象失败");
    }
  }

  /**
   * 修改对象部分字段
   *
   * @param dto 修改对象
   * @return int
   */
  @Transactional
  public int updateSensitive(AssetCatalogAuthDTO dto) {
    try {
      int count = assetCatalogAuthDAO.updateSensitive(getUpdateDto(dto));
      if (count == 0) {
        throw new BusinessException("数据失效，请重新更新");
      }
      return count;
    } catch (Exception e) {
      logger.error(e.getMessage(), e);
      throw new BusinessException("修改对象失败");
    }
  }

  /** 内部方法，获取修改的dto对象 */
  private AssetCatalogAuthDTO getUpdateDto(AssetCatalogAuthDTO dto) {
    AssetCatalogAuthDTO oldDTO = findById(dto.getId());
    if (oldDTO == null) {
      throw new BusinessException("数据不存在");
    }
    // 记录日志
    SysLogUtil.log4Update(dto, oldDTO);
    PojoUtil.setSysProperties(dto, PlatformConstant.OpType.update);
    PojoUtil.copyProperties(oldDTO, dto, false);
    return oldDTO;
  }

  /**
   * 按主键单条删除
   *
   * @param id 主键id
   * @return int
   */
  @Transactional
  public int deleteById(String id) {
    if (StringUtils.isEmpty(id)) {
      throw new BusinessException("删除失败！传入的参数主键为null");
    }
    try {
      // 记录日志
      AssetCatalogAuthDTO dto = findById(id);
      if (dto == null) {
        throw new BusinessException("删除失败！对象不存在");
      }
      SysLogUtil.log4Delete(dto);
      // 删除业务数据
      return assetCatalogAuthDAO.deleteById(id);
    } catch (Exception e) {
      logger.error(e.getMessage(), e);
      throw new BusinessException("删除失败");
    }
  }

  /**
   * 批量删除数据
   *
   * @param ids id的数组
   * @return int
   */
  @Transactional
  public int deleteByIds(String ids) {
    int result = 0;
    if (StringUtils.isNotEmpty(ids)) {
      for (String id : ids.split(Constants.COMMA)) {
        deleteById(id);
        result++;
      }
    }
    return result;
  }

  /**
   * 日志专用，内部方法，不再记录日志
   *
   * @param id 主键id
   */
  private AssetCatalogAuthDTO findById(String id) {
    return assetCatalogAuthDAO.findById(id);
  }
}
